package com.heima.xiyuanmall.sudoku

import android.view.View

/**
 * @author flutterdash@qq.com
 * @since 2021/10/3 20:00
 */
typealias FP = FontProp

data class CellStyle(
    val pos: Pos,
    val renderer: StyleRenderer
) {

    override fun equals(other: Any?): Boolean {
        if (other == null) return false
        return if (other is CellStyle) {
            other.pos == this.pos
        } else {
            false
        }
    }

    override fun hashCode(): Int = pos.hashCode()
}

sealed class EventsHolder

data class RenderEventsHolder(
    val events: Collection<CellStyle>
) : EventsHolder()

data class StyleDesc(
    val prospect: String,
    val background: String,
    val fontProp: FontProp
)

enum class FontProp {
    BOLD, ITALICS, DEFAULT, UNSET, BOLD_ITALICS
}

private val onSearchedStyle = StyleDesc("正在搜索的位置", "", FP.UNSET)
private val onSelectedStyle = StyleDesc("被选中的位置", "", FP.ITALICS)
private val onPassedStyle = StyleDesc("已路过的位置", "", FP.BOLD_ITALICS)
private val onSpaceStyle = StyleDesc("空白没有数字的位置", "", FP.DEFAULT)
private val onFixedStyle = StyleDesc("已存在固定数字的位置", "", FP.BOLD)

@FunctionalInterface
fun interface StyleRenderer {
    fun render(view: View)
}

private fun doRender(view: View, vararg styles: StyleDesc): Unit =
    TODO(
        """
    todolist: 
        设置背景色,
        设置前景色,
        设置字体样式
""".trimIndent()
    )

private val onSearchedStyleRenderer = StyleRenderer { doRender(it, onSearchedStyle) }
private val onSelectedStyleRenderer = StyleRenderer { doRender(it, onSelectedStyle) }
private val onPassedStyleRenderer = StyleRenderer { doRender(it, onPassedStyle) }
private val onSpaceStyleRenderer = StyleRenderer { doRender(it, onSpaceStyle) }
private val onFixedStyleRenderer = StyleRenderer { doRender(it, onFixedStyle) }

/**
 * 渲染事件发射器
 *
 * 事件1: 初始化事件
 * 在数独界面初始化的时候, 将所有单元格样式初始化
 *
 * 事件2: 选中事件
 * 数独自动解析器开始运行, 并且选中了一个空白的位置, 在这个位置上尝试数字
 *     step 1. 将这个位置的行和列, 以及所在的方块, 背景色加深,
 *     step 2. 显示这个位置要尝试的数字, 字体样式倾斜, 背景加深(比其他位置要深)
 *
 * 事件3: 转移事件
 * 在选中事件后, 将要选中下一个位置
 *     step 1. 恢复之前选中事件所修改的单元格的背景色为默认, 将当前位置的字体设置为绿色加粗
 *
 * 事件4: 取消选中
 * 当前位置所有数字都不可用
 *     step 1. 将当前位置恢复成默认格式, 并不显示数字
 *
 * 事件5: 完成事件
 * 数独自动解析器运行结束, 已找到所有位置的解, 将有解的位置字体设置为加粗绿色
 *
 */
object RenderEventEmitter {

    fun initEvent() {
    }

    fun selectedEvent(pos: Pos): RenderEventsHolder {
        val scope = getScopeOf(pos)
        val events = zip(scope, onSearchedStyleRenderer)
        events.add(CellStyle(pos, onSelectedStyleRenderer))
        return RenderEventsHolder(events)
    }

    fun transferEvent(pos: Pos): RenderEventsHolder {
        val scope = getScopeOf(pos)
        val events = zip(scope, onSpaceStyleRenderer)
        events.add(CellStyle(pos, onPassedStyleRenderer))
        return RenderEventsHolder(events)
    }

    fun uncheckEvent(pos: Pos): RenderEventsHolder {
        return RenderEventsHolder(listOf(CellStyle(pos, onSpaceStyleRenderer)))
    }

    fun finishEvent(pos: Pos): RenderEventsHolder = TODO()

    private fun zip(
        positions: Collection<Pos>, renderer: StyleRenderer, cap: Int = 32
    ): HashSet<CellStyle> {
        return HashSet<CellStyle>(cap).apply {
            for (pos in positions) {
                add(CellStyle(pos, renderer))
            }
        }
    }
}
